package com.yfqy.admin.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.yfqy.admin.constant.MyConstants;
import com.yfqy.admin.domain.dto.auth.AuthMenu;
import com.yfqy.admin.domain.dto.auth.AuthRole;
import com.yfqy.admin.domain.dto.auth.AuthUser;
import com.yfqy.admin.domain.dto.auth.Authority;
import com.yfqy.admin.domain.entity.SysRole;
import com.yfqy.admin.domain.entity.SysUser;
import com.yfqy.admin.domain.mapper.SysMenuMapper;
import com.yfqy.admin.domain.mapper.SysRoleMapper;
import com.yfqy.admin.domain.mapper.SysUserMapper;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 使用redis缓存登录用户的角色+权限code
 */
@Service
public class RefreshAuthority {

    private static final Logger logger = LoggerFactory.getLogger(RefreshAuthority.class);

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysMenuMapper menuMapper;
    @Autowired
    @Qualifier("singleRedisClient")
    private RedissonClient redissonClient;

    public void refreshAuthorityBySysUserId(Long userId) {
        String key = String.format(MyConstants.SYS_USER_TOKEN, userId);
        RBucket<Object> rBucket = redissonClient.getBucket(key);
        if (rBucket.get() == null) {
            logger.info("异步刷新后台管理员权限，用户key不存在直接return，key:{}", key);
            return;
        }
        SysUser user = userMapper.selectByPrimaryKey(userId);
        if (user == null) {
            logger.warn("异步刷新后台管理员权限，用户不存在直接return，userId:{}", userId);
            return;
        }
        if (user.getStatus() != MyConstants.BT1) {
            logger.info("异步刷新后台管理员权限，用户被锁定或已删除，userId:{}, 清理redis中保存的用户权限", userId);
            rBucket.delete();
            return;
        }
        // 合并角色和权限
        List<AuthRole> roles = roleMapper.selectRolesByUserId(user.getId());
        List<AuthMenu> menus = null;
        if (CollUtil.isEmpty(roles)) {
            return;
        } else if (roles.stream().anyMatch(role -> role.getIsAdmin() == 1)) {
            menus = menuMapper.selectMenusByAdmin();
        } else {
            List<Long> roleIds = roles.stream().map(AuthRole::getId).toList();
            menus = menuMapper.selectMenusByRoleIds(roleIds);
        }
        List<Map<String, String>> authorityMapList = Stream.concat(
                // 1. 处理角色（ROLE_XXX）
                roles.stream()
                        .map(role -> Map.of("authority", "ROLE_" + role.getCode())),

                // 2. 处理权限
                Optional.ofNullable(menus)
                        .orElse(Collections.emptyList())
                        .stream()
                        .filter(perm -> perm != null && StringUtils.isNotBlank(perm.getCode()))
                        .map(perm -> Map.of("authority", perm.getCode()))
        ).collect(Collectors.toList());
        rBucket.set(JSONUtil.toJsonStr(authorityMapList), 30L, TimeUnit.DAYS);
    }
}
